package com.yc.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipOutputStream;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.zip.ZipEntry;

public class CompressUtil {
	
	public static void main(String[] args) {
		String resourcesPath = "C:/Users/yuancan/.shr/temp/zip1563276160665";
		String targetPath = "C:/Users/yuancan/.shr/temp";
		try {
			compressedFile(resourcesPath, targetPath);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//----------------------------------------------------

    private void zip(ZipOutputStream out, File f, String base) throws Exception
    {
        if (f.isDirectory()) {
            File[] files = f.listFiles();
            base = (base.length() == 0 ? "" : base + "/");
            for (int i = 0; i < files.length; i++) {
                zip(out, files[i], base + files[i].getName());
            }
        } else {
            out.putNextEntry(new ZipEntry(base));
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
            int c;
            
            while ((c = in.read()) != -1) {
                out.write(c);
            }
            in.close();
        }
    }
    
    private void zip(File inputFileName, String zipFileName) throws Exception
    {
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
        zip(out, inputFileName, "");
        out.close();
	
    }
	//------------------------------------------------------

	/**
	 * @desc 将源文件/文件夹生成指定格式的压缩文件,格式zip
	 * @param resourePath 源文件/文件夹
	 * @param targetPath  目的压缩文件保存路径
	 * @return void
	 * @throws Exception
	 */
	public static void compressedFile(String resourcesPath, String targetPath) throws Exception {
		File resourcesFile = new File(resourcesPath); // 源文件
		File targetFile = new File(targetPath); // 目的
		// 如果目的路径不存在，则新建
		if (!targetFile.exists()) {
			targetFile.mkdirs();
		}

		String targetName = resourcesFile.getName() + ".zip"; // 目的压缩文件名
		FileOutputStream outputStream = new FileOutputStream(targetPath + "\\" + targetName);
		ZipOutputStream out = null;
		try {
			out = new ZipOutputStream(new BufferedOutputStream(outputStream));
			createCompressedFile(out, resourcesFile, "");
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}
	}

	/**
	 * @desc 生成压缩文件。 如果是文件夹，则使用递归，进行文件遍历、压缩 如果是文件，直接压缩
	 * @param out  输出流
	 * @param file 目标文件
	 * @return void
	 * @throws IOException
	 * @throws Exception
	 */
	public static void createCompressedFile(ZipOutputStream out, File file, String dir) throws IOException {
		 // 当前的是文件，打包处理
		FileInputStream fis = null;
		try {
			// 文件输入流
			fis = new FileInputStream(file);

			out.putNextEntry(new ZipEntry(dir));
			// 进行写操作
			int j = 0;
			byte[] buffer = new byte[1024];
			while ((j = fis.read(buffer)) > 0) {
				out.write(buffer, 0, j);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭输入流
			if (null != fis) {
				fis.close();
			}
		}
	}

	/**
	 * 解压zip格式压缩包 对应的是ant.jar
	 */
	private static void unzip(String sourceZip, String destDir) throws Exception {
		try {
			Project p = new Project();
			Expand e = new Expand();
			e.setProject(p);
			e.setSrc(new File(sourceZip));
			e.setOverwrite(false);
			e.setDest(new File(destDir));
			/*
			 * ant下的zip工具默认压缩编码为UTF-8编码， 而winRAR软件压缩是用的windows默认的GBK或者GB2312编码 所以解压缩时要制定编码格式
			 */
			e.setEncoding("gbk");
			e.execute();
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 解压缩
	 */
	public static void deCompress(String sourceFile, String destDir) throws Exception {
		// 保证文件夹路径最后是"/"或者"\"
		char lastChar = destDir.charAt(destDir.length() - 1);
		if (lastChar != '/' && lastChar != '\\') {
			destDir += File.separator;
		}
		// 根据类型，进行相应的解压缩
		String type = sourceFile.substring(sourceFile.lastIndexOf(".") + 1);
		if (type.equals("zip")) {
			CompressUtil.unzip(sourceFile, destDir);
		} else {
			throw new Exception("只支持zip的压缩包！");
		}
	}
}
